home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1997 May
/
EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso
/
softwareupdate
/
system
/
amigados
/
files
/
example5.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-10-10
|
14KB
|
453 lines
/***********************************************************/
/* */
/* Amiga C Encyclopedia (ACE) Amiga C Club (ACC) */
/* -------------------------- ------------------ */
/* */
/* Manual: AmigaDOS Amiga C Club */
/* Chapter: Files Tulevagen 22 */
/* File: Example5.c 181 41 LIDINGO */
/* Author: Anders Bjerin SWEDEN */
/* Date: 93-03-13 */
/* Version: 1.2 */
/* */
/* Copyright 1993, Anders Bjerin - Amiga C Club (ACC) */
/* */
/* Registered members may use this program freely in their */
/* own commercial/noncommercial programs/articles. */
/* */
/***********************************************************/
/* This example demonstrates how you can write a (very) simple */
/* data base program. In this data base you can add names of */
/* persons and their telephone numbers. Whenever you want you */
/* can display the complete user list. */
/* */
/* This example uses a "Console" window which has not been */
/* explained yet. It is therefore a bit difficult, and if you */
/* are unfamiliar with AmigaDOS you should skip this example */
/* for the moment and look at it later. */
/* In this example we are using a "Console window" in which we */
/* do the conversation with the user. Please note that I have */
/* not described Console windows yet (you can read abut it in */
/* chapter 6 "Handlers") so you should simply skip all parts */
/* which has to do with the Console. */
/* */
/* In the example we use two special functions, "print_text()", */
/* and "collect_text()". They use the Console window and are */
/* similar to the normal "printf()" and "scanf()" routines. The */
/* reason why I use a Console window rather than using the */
/* printf() and scanf() functions directly is because these */
/* normal C functions, printf() and scanf(),are not very */
/* practical (and you usually ends up with a lot of buffered */
/* signs which are tricky to avoid). The Console is therefore */
/* much easier to work with and looks better. */
/* */
/* When you later read about the "handlers" and "Console" */
/* windows you can take a look on this example again. It is a */
/* rather good demonstration on how to use Console windows. */
/* Include the dos library definitions: */
#include <dos/dos.h>
/* Now we include the necessary function prototype files: */
#include <clib/dos_protos.h> /* General dos functions... */
#include <clib/exec_protos.h> /* System functions... */
#include <stdio.h> /* Std functions [printf()...] */
#include <stdlib.h> /* Std functions [exit()...] */
#include <string.h> /* Std functions [strlen()...] */
/* The maximum length of the strings: */
#define MAX_MENU_LENGTH 10
#define MAX_NAME_LENGTH 50
#define MAX_PHONE_LENGTH 20
/* Set name and version number: */
UBYTE *version = "$VER: AmigaDOS/InputOutput/Example5 1.2";
/* The information will be stored in this type of structure: */
struct person
{
UBYTE name[ MAX_NAME_LENGTH ];
UBYTE phone[ MAX_PHONE_LENGTH ];
};
/* In this example we will use the "person" structure to */
/* store information about a user in. The structure will be */
/* saved in a file so we later can retreive the information */
/* when we want to list all users. When I refer to this */
/* structure I will call it a "record". */
/* Declared our own functions: */
/* Our main function: */
int main( int argc, char *argv[] );
/* Adds a person to the user list: */
BOOL add_person( BPTR my_file, BPTR my_console );
/* Displays the complete user list: */
BOOL show_userlist( BPTR my_file, BPTR my_console );
/* Prints a string in a file (in our example a Console window): */
int print_text( BPTR file, STRPTR text );
/* Collects input from a file (in our example a Console window): */
int collect_text( BPTR file, STRPTR text, int max_length );
/* Main function: */
int main( int argc, char *argv[] )
{
/* A "BCPL" pointer to our file: */
BPTR my_userfile;
/* A "BCPL" pointer to our "Console" window: */
BPTR my_console;
/* Boolean value to see if we should */
/* stay in the main loop or not: */
BOOL work;
/* Store here what the user type in: */
UBYTE user_input[ MAX_MENU_LENGTH ];
/* What menu option the user selected: */
int menu_option;
/* First we will open a "Console window" in which we */
/* can do all the conversation with user: */
my_console =
Open( "CON:0/0/400/200/SUPERBASE 5", MODE_NEWFILE );
/* Could we open the Console window? */
if( !my_console )
{
/* Inform the user: */
printf( "Error! Could not open the Console window!\n" );
/* Exit with an error code: */
exit( 20 );
}
/* Open the user file: (If the file exists it will be opened as an */
/* old file, and if the file does not exist it will be created.) */
my_userfile = Open( "RAM:UserList.dat", MODE_READWRITE );
/* Have we opened the file successfully? */
if( !my_userfile )
{
/* Inform the user: */
printf( "Error! Could not open the file!\n" );
/* Close the Console window: */
Close( my_console );
/* Exit with an error code: */
exit( 21 );
}
/* Run at least one time in while loop: */
work = TRUE;
/* Stay in the while loop as long as the user want to continue: */
while( work )
{
/* Print the menu: */
print_text( my_console,
"\nMenu:\n1. Add new person\n2. Show all persons\n9. Quit\n=> " );
/* Collect menu option: */
collect_text( my_console, user_input, MAX_MENU_LENGTH );
/* Convert the string into a number: */
menu_option = atoi( user_input );
/* Execute the option: */
switch( menu_option )
{
case 9: work = FALSE; break;
case 1: add_person( my_userfile, my_console ); break;
case 2: show_userlist( my_userfile, my_console ); break;
default: print_text( my_console,
"Select one of the options 1, 2 or 9!\n" );
}
}
/* Close the file: */
Close( my_userfile );
/* Close the Console window: */
Close( my_console );
/* Some final messages... */
printf( "Thank you for using SUPERBASE 5!\n" );
printf( "The userlist has been saved so you can\n" );
printf( "continue to add information later on...\n" );
/* The End! */
exit( 0 );
}
/* Asks the user to enter some information about a person. */
/* The information will then be added at the end of the */
/* user file. Returns FALSE if the data could not be saved, */
/* else TRUE is returned. */
BOOL add_person
(
BPTR my_file,
BPTR my_console
)
{
/* Declare a person structure: */
struct person new;
/* Store here the number of bytes actually written: */
long bytes_written;
/* Info to the user: */
print_text( my_console, "Add new person!\n" );
/* Name: (An empty string is not accepted) */
new.name[ 0 ] = NULL;
while( new.name[ 0 ] == NULL )
{
print_text( my_console, "Name: " );
collect_text( my_console, new.name, MAX_NAME_LENGTH );
}
/* Phone: (An empty string is not accepted) */
new.phone[ 0 ] = NULL;
while( new.phone[ 0 ] == NULL )
{
print_text( my_console, "Phone: " );
collect_text( my_console, new.phone, MAX_PHONE_LENGTH );
}
/* Move the file cursor to the end of the file: */
/* (We have to make sure that the file cursor is */
/* standing at the endo of the file so nothing */
/* will be overwritten when we save the info.) */
Seek( my_file, 0, OFFSET_END );
/* Store the information about the person: ("new" is the structure */
/* we want to save, and since the function needs a pointer to the */
/* memory that should be saved we put a "&" sign in front of the */
/* structure name. The size of the structure can easily be */
/* calculated with help of the "sizeof()" function.) */
bytes_written = Write( my_file, &new, sizeof( struct person ) );
/* Could we save all data? */
if( bytes_written != sizeof( struct person ) )
{
/* No! The number of bytes actually written */
/* was less than what we wanted to write! */
print_text( my_console, "Error! Could not save the data!\n" );
/* Well, there is not much we can do about it now, */
/* we return an error message, but that is all. */
return( FALSE );
}
else
{
/* Yes, all bytes were successfully saved! */
print_text( my_console, "Person added to the userlist!\n" );
}
/* OK! */
return( TRUE );
}
/* Displays the complete user list. Returns TRUE if all users */
/* were successfully listed, else FALSE is returned. */
BOOL show_userlist
(
BPTR my_file,
BPTR my_console
)
{
/* Declare a person structure: */
struct person current_person;
/* Store here the number of bytes actually collected: */
long bytes_read;
/* Move the file cursor to the beginning of the file: */
/* (We want to read all records in this file, and */
/* consequently we have to move to the first record */
/* in the file.) */
Seek( my_file, 0, OFFSET_BEGINNING );
/* Stay in the loop until we return to the main function: */
while( TRUE )
{
/* Collect a record: */
bytes_read = Read( my_file, ¤t_person, sizeof( struct person ) );
/* Could we collect enough data to fill a record? */
if( bytes_read != sizeof( struct person ) )
{
/* No, we cold not fill a record! This means that */
/* we have either reached the end of the file, or */
/* there was an error. Read() returns 0 when we */
/* reach the end of the file, and -1 if there was */
/* an error. (If some data was collected but not */
/* all this would be an error in our program */
/* since we expect to find complete records, so */
/* any value which is non zero means that there */
/* was an error.) */
if( bytes_read == 0 )
{
/* We have simpy reached the end of the file! */
/* Inform the user: */
print_text( my_console, "End of user list!\n" );
/* Return happily: */
return( TRUE );
}
else
{
/* Problems! Inform the user: */
print_text( my_console, "ERROR while reading user record!\n" );
/* Return with an error code: */
return( FALSE );
}
}
/* Print the information about the user: */
print_text( my_console, "Name: " );
print_text( my_console, current_person.name );
print_text( my_console, "\nPhone: " );
print_text( my_console, current_person.phone );
print_text( my_console, "\n\n" );
}
}
/********************************************************/
/* DO NOT BOTHER ABOUT THESE FUNCTIONS LISTED BELOW!! */
/* THEY WILL BE FULLY EXPLAINED IN CHAPTER 6 "HANDLERS" */
/********************************************************/
/* Writes text to an already opened file, and returns */
/* the number of characters actualy written. */
int print_text
(
BPTR file,
STRPTR text
)
{
/* Store the number of characters (bytes) actualy written here: */
int characters_written;
/* Write the text: */
characters_written = Write( file, text, strlen( text ) );
/* Returns the number of characters actually written: */
return( TRUE );
}
/* Collects text from an already opened file, and returns */
/* the number of characters collected. */
int collect_text
(
BPTR file,
STRPTR text,
int max_length
)
{
/* Store the number of characters (bytes) actualy read here: */
int characters_read;
/* Collect some text: */
characters_read = Read( file, text, max_length );
/* To be able to print the text we need to put a NULL sign */
/* at the end of the string. (All strings must end with a */
/* NULL sign, otherwise the functions would not know when */
/* the string ends.) To get rid of the Enter sign we simply */
/* substitute it with a NULL sign: */
/* Put the NULL ('\0') sign at the end of the string: */
if( characters_read > 0 )
{
/* Substitute the Enter sign with a NULL sign: */
text[ characters_read - 1 ] = NULL;
/* We got at least some text: (maybe only an */
/* Enter sign but that is OK!) */
return( TRUE );
}
else
{
/* Nothing was entered, not even an Enter sign! */
/* The console window has been closed! */
printf( "The console window was closed!\n" );
/* Clear the string: (Set a NULL sign in the begining) */
text[ characters_read ] = NULL;
/* Since the window was closed we return FALSE: */
/* (In this example we ignore any returned values, */
/* but if you copy this function to your own */
/* program you might want to use the returend */
/* values.) */
return( FALSE );
}
}